package com.zp.business.impl.prescription;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zp.base.api.RemoteClinicItemDictService;
import com.zp.base.api.RemoteSerialNumberUtils;
import com.zp.base.api.vo.ClinicItemDictVo;
import com.zp.base.api.vo.PriceListVo;
import com.zp.business.api.diagnosis.HisDiagnosisBo;
import com.zp.business.api.prescription.PrescriptionApply;
import com.zp.business.api.prescription.PrescriptionItem;
import com.zp.business.api.prescription.bo.PrescriptionApplyBo;
import com.zp.business.api.prescription.bo.PrescriptionItemBo;
import com.zp.business.api.prescription.vo.PrescriptionApplyVo;
import com.zp.business.entity.clinicOrder.ClinicOrders;
import com.zp.business.entity.clinicOrder.ClinicOrdersCost;
import com.zp.business.entity.clinicOrder.OutpTreatRec;
import com.zp.business.entity.clinicOrder.bo.ApplyItemBo;
import com.zp.business.entity.clinicOrder.bo.ClinicOrderParam;
import com.zp.business.entity.clinicOrder.bo.ClinicOrdersBo;
import com.zp.business.entity.clinicOrder.vo.ClinicOrdersVo;
import com.zp.business.entity.outpFees.bo.OutpFeesMasterBo;
import com.zp.business.mapper.prescription.PrescriptionApplyMapper;
import com.zp.business.service.clinicOrder.IClinicOrdersCostService;
import com.zp.business.service.clinicOrder.IClinicOrdersService;
import com.zp.business.service.clinicOrder.IOutpTreatRecService;
import com.zp.business.service.outpFees.IOutpFeesMasterService;
import com.zp.business.service.patient.IClinicMasterService;
import com.zp.business.service.prescription.IPrescriptionApplyService;
import com.zp.business.service.prescription.IPrescriptionItemService;
import com.zp.common.core.constant.BaseConstants;
import com.zp.common.core.constant.CacheNames;
import com.zp.common.core.constant.UserConstants;
import com.zp.common.core.utils.DateUtils;
import com.zp.common.core.utils.StringUtils;
import com.zp.common.myBatis.core.page.PageQuery;
import com.zp.common.myBatis.core.page.TableDataInfo;
import com.zp.common.redis.utils.CacheUtils;
import com.zp.common.satoken.utils.LoginHelper;
import com.zp.system.api.RemoteOrgDictDataService;
import com.zp.system.api.entity.SysDept;
import com.zp.system.api.entity.SysOrgDict;
import com.zp.system.api.entity.SysUser;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;

/**
 * 处方主表Service业务层处理
 *
 * @author zhang peng
 * @ date 2024-03-22
 */
@RequiredArgsConstructor
@Service
public class PrescriptionApplyServiceImpl implements IPrescriptionApplyService {

    private final PrescriptionApplyMapper baseMapper;

    /**
     * 用户信息
     */
    static Map<String, SysUser> sysUserMap = CacheUtils.get(CacheNames.SYS_USER);
    static Map<String, SysDept> sysDeptMap = CacheUtils.get(CacheNames.SYS_DEPT);
    private final IPrescriptionItemService prescriptionItemService;
    private final IClinicOrdersService clinicOrdersService;
    private final IClinicOrdersCostService clinicOrdersCostService;
    private final IOutpTreatRecService outpTreatRecService;
    private final IClinicMasterService clinicMasterService;
    @DubboReference
    private RemoteSerialNumberUtils remoteSerialNumberUtils;
    @DubboReference
    private RemoteClinicItemDictService remoteClinicItemDictService;
    @DubboReference
    private RemoteOrgDictDataService orgDictDataService;

//    @DubboReference
//    private RemoteOutpFeesMasterService remoteOutpFeesMasterService;

    private final IOutpFeesMasterService outpFeesMasterService;


    /**
     * 查询处方主表
     */
    @Override
    public PrescriptionApplyVo queryById(String applyId) {
        return baseMapper.selectVoById(applyId);
    }

    /**
     * 查询处方主表列表(分页)
     */
    @Override
    public TableDataInfo<PrescriptionApplyVo> queryPageList(PrescriptionApplyBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<PrescriptionApply> lqw = buildQueryWrapper(bo);
        Page<PrescriptionApplyVo> result = baseMapper.selectVoPage(pageQuery.build(), bo);
        result.getRecords().forEach(item -> {
            item.setApplyDeptName(StringUtils.isNotBlank(item.getApplyDept()) && CollectionUtil.isNotEmpty(sysDeptMap)
                    ? sysDeptMap.get(item.getApplyDept()).getDeptName() : "");
            item.setImplementDepName(StringUtils.isNotBlank(item.getImplementDept()) && CollectionUtil.isNotEmpty(sysDeptMap)
                    ? sysDeptMap.get(item.getImplementDept()).getDeptName() : "");
            item.setApplyUserName(StringUtils.isNotBlank(item.getApplyUser()) && CollectionUtil.isNotEmpty(sysUserMap)
                    ? sysUserMap.get(item.getApplyUser()).getNickName() : "");
            item.setImplementUserName(StringUtils.isNotBlank(item.getImplementUser()) && CollectionUtil.isNotEmpty(sysUserMap)
                    ? sysUserMap.get(item.getImplementUser()).getNickName() : "");
        });
        return TableDataInfo.build(result);
    }

    /**
     * 查询处方主表列表(不分页)
     */
    @Override
    public List<PrescriptionApplyVo> queryList(PrescriptionApplyBo bo) {
        LambdaQueryWrapper<PrescriptionApply> lqw = buildQueryWrapper(bo);
        List<PrescriptionApplyVo> prescriptionApplyVos = baseMapper.selectVoList(lqw);
        prescriptionApplyVos.forEach(item -> {
            item.setApplyDeptName(StringUtils.isNotBlank(item.getApplyDept()) && CollectionUtil.isNotEmpty(sysDeptMap)
                    ? sysDeptMap.get(item.getApplyDept()).getDeptName() : "");
            item.setImplementDepName(StringUtils.isNotBlank(item.getImplementDept()) && CollectionUtil.isNotEmpty(sysDeptMap)
                    ? sysDeptMap.get(item.getImplementDept()).getDeptName() : "");
            item.setApplyUserName(StringUtils.isNotBlank(item.getApplyUser()) && CollectionUtil.isNotEmpty(sysUserMap)
                    ? sysUserMap.get(item.getApplyUser()).getNickName() : "");
            item.setImplementUserName(StringUtils.isNotBlank(item.getImplementUser()) && CollectionUtil.isNotEmpty(sysUserMap)
                    ? sysUserMap.get(item.getImplementUser()).getNickName() : "");
        });
        return prescriptionApplyVos;
    }

    private LambdaQueryWrapper<PrescriptionApply> buildQueryWrapper(PrescriptionApplyBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<PrescriptionApply> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getClinicId()), PrescriptionApply::getClinicId, bo.getClinicId());
        lqw.eq(StringUtils.isNotBlank(bo.getVisitId()), PrescriptionApply::getVisitId, bo.getVisitId());
        lqw.eq(StringUtils.isNotBlank(bo.getOrdersId()), PrescriptionApply::getOrdersId, bo.getOrdersId());
        lqw.eq(StringUtils.isNotBlank(bo.getApplyNo()), PrescriptionApply::getApplyNo, bo.getApplyNo());
        lqw.eq(StringUtils.isNotBlank(bo.getPatientId()), PrescriptionApply::getPatientId, bo.getPatientId());
        lqw.eq(StringUtils.isNotBlank(bo.getInoroutFlag()), PrescriptionApply::getInoroutFlag, bo.getInoroutFlag());
        lqw.eq(StringUtils.isNotBlank(bo.getChargeFlag()), PrescriptionApply::getChargeFlag, bo.getChargeFlag());
        lqw.eq(StringUtils.isNotBlank(bo.getChargeFlag()), PrescriptionApply::getChargeFlag, bo.getChargeFlag());
        lqw.eq(StringUtils.isNotBlank(bo.getImplementDept()), PrescriptionApply::getImplementDept, bo.getImplementDept());
        lqw.eq(StringUtils.isNotBlank(bo.getPrescAttr()), PrescriptionApply::getPrescAttr, bo.getPrescAttr());
        lqw.eq(StringUtils.isNotBlank(bo.getItemClass()), PrescriptionApply::getItemClass, bo.getItemClass());
        lqw.eq(StringUtils.isNotBlank(bo.getPrescStatus()), PrescriptionApply::getPrescStatus, bo.getPrescStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getOrgId()), PrescriptionApply::getOrgId, bo.getOrgId());
        lqw.eq(StringUtils.isNotBlank(bo.getApplyDept()), PrescriptionApply::getApplyDept, bo.getApplyDept());
        lqw.eq(StringUtils.isNotBlank(bo.getImplementUser()), PrescriptionApply::getImplementUser, bo.getImplementUser());
        lqw.eq(bo.getGrantTime() != null, PrescriptionApply::getGrantTime, bo.getGrantTime());
        lqw.eq(StringUtils.isNotBlank(bo.getRemarks()), PrescriptionApply::getRemarks, bo.getRemarks());
        lqw.eq(StringUtils.isNotBlank(bo.getIsTemplate()), PrescriptionApply::getIsTemplate, bo.getIsTemplate());
        lqw.eq(StringUtils.isNotBlank(bo.getAgencyBy()), PrescriptionApply::getAgencyBy, bo.getAgencyBy());
        lqw.eq(StringUtils.isNotBlank(bo.getAgencyNo()), PrescriptionApply::getAgencyNo, bo.getAgencyNo());
        lqw.eq(StringUtils.isNotBlank(bo.getAgencyAge()), PrescriptionApply::getAgencyAge, bo.getAgencyAge());
        lqw.eq(StringUtils.isNotBlank(bo.getAgencySex()), PrescriptionApply::getAgencySex, bo.getAgencySex());
        lqw.eq(StringUtils.isNotBlank(bo.getOrdersFlag()), PrescriptionApply::getOrdersFlag, bo.getOrdersFlag());
        lqw.eq(StringUtils.isNotBlank(bo.getOperationFlag()), PrescriptionApply::getOperationFlag, bo.getOperationFlag());
        lqw.like(StringUtils.isNotBlank(bo.getDecoctionName()), PrescriptionApply::getDecoctionName, bo.getDecoctionName());
        lqw.eq(StringUtils.isNotBlank(bo.getReturnDrugUser()), PrescriptionApply::getReturnDrugUser, bo.getReturnDrugUser());
        lqw.eq(bo.getReturnDrugTime() != null, PrescriptionApply::getReturnDrugTime, bo.getReturnDrugTime());
        lqw.eq(StringUtils.isNotBlank(bo.getDiagnosis()), PrescriptionApply::getDiagnosis, bo.getDiagnosis());
        lqw.like(StringUtils.isNotBlank(bo.getIcdName()), PrescriptionApply::getIcdName, bo.getIcdName());
        lqw.eq(StringUtils.isNotBlank(bo.getIcdCode()), PrescriptionApply::getIcdCode, bo.getIcdCode());
        lqw.eq(StringUtils.isNotBlank(bo.getIsDecoction()), PrescriptionApply::getIsDecoction, bo.getIsDecoction());
        lqw.eq(StringUtils.isNotBlank(bo.getDiagnosisId()), PrescriptionApply::getDiagnosisId, bo.getDiagnosisId());
        lqw.orderByDesc(PrescriptionApply::getCreateTime);
        return lqw;
    }

    /**
     * 新增处方主表
     */
    @Override
    @Transactional
    public Boolean insertByBo(PrescriptionApplyBo bo) {
        boolean flag = false;
        if (StringUtils.isEmpty(bo.getApplyId())) {
            flag = saveInfo(bo);
        } else {
            PrescriptionApplyVo vo = baseMapper.selectVoById(bo.getApplyId());
            Boolean b = deleteInfo(vo);
            if (b) {
                bo.setApplyNo(vo.getApplyNo());
                bo.setCreateTime(vo.getCreateTime());
                bo.setUpdateTime(DateUtils.getNowDate());
                bo.setUpdateBy(bo.getApplyUser());
                flag = saveInfo(bo);
            }
        }
        return flag;
    }

    /**
     * 最终保存
     *
     * @return
     */
    @GlobalTransactional
    public Boolean saveInfo(PrescriptionApplyBo bo) {
        boolean flag = false;
        HisDiagnosisBo hisDiagnosisBo = bo.getDiagnosisList();
        if (ObjectUtil.isNotEmpty(hisDiagnosisBo)) {
            bo.setIcdName(hisDiagnosisBo.getIcdName());
            bo.setIcdCode(hisDiagnosisBo.getIcdCode());
            bo.setDiagnosisId(hisDiagnosisBo.getId());
            bo.setDiagnosis(hisDiagnosisBo.getId() + "|" + hisDiagnosisBo.getIcdName());
        }
        bo.setItemClass(bo.getDrugClass());
        // 发药状态
        bo.setConfirmFlag(BaseConstants.CONFIRM_FLAG.UNISSUED);
        // 收费状态
        bo.setChargeFlag(BaseConstants.CHARGE_FLAG_DICT.ONE);
        bo.setIsTemplate(UserConstants.NO);
        bo.setPrescStatus(UserConstants.YES);
        if (StringUtils.isEmpty(bo.getApplyNo())) {
            bo.setApplyNo(remoteSerialNumberUtils.generatePrescriptionNo(BaseConstants.IS_CLINIC, bo.getOrgId()));
        }
        PrescriptionApply add = BeanUtil.toBean(bo, PrescriptionApply.class);
        validEntityBeforeSave(add);
        add.initEntity();
        flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setApplyId(add.getApplyId());
            // 保存处方明细
            List<PrescriptionItemBo> prescriptionItemBoList = savePrescriptionItem(bo);
            // 组织门诊待收费信息数据（clinicOrder）等信息
            ClinicOrderParam clinicOrderParam = new ClinicOrderParam();
            // 设置是否为附加费用(否)
            clinicOrderParam.setWhetherToComeInAttached(UserConstants.NO);
            // 设置诊疗项目类型
            clinicOrderParam.setItemClass(bo.getItemClass());
            clinicOrderParam.setClinicId(bo.getClinicId());
            clinicOrderParam.setPatientId(bo.getPatientId());
            clinicOrderParam.setDiagnosis(bo.getIcdName());
            clinicOrderParam.setOrgId(bo.getOrgId());
            clinicOrderParam.setIsApply(UserConstants.YES);
            clinicOrderParam.setApplyNo(bo.getApplyNo());
            clinicOrderParam.setApplyUser(bo.getApplyUser());
            clinicOrderParam.setApplyDept(bo.getApplyDept());
            clinicOrderParam.setImplementUser(bo.getImplementUser());
            clinicOrderParam.setImplementDept(bo.getImplementDept());
            clinicOrderParam.setInoroutFlag(bo.getInoroutFlag());
            // 拼装clinicOrder实体数据
            ClinicOrders clinicOrders = clinicOrdersService.getClinicOrders(clinicOrderParam);
            // 保存clinicOrder数据
            ClinicOrdersVo clinicOrdersVo = clinicOrdersService.insertByBo(BeanUtil.toBean(clinicOrders, ClinicOrdersBo.class));
            // 保存 clinicOrdersCost、outpTreatRec数据
            Map<String, Object> map = saveClinicOrderCost(clinicOrdersVo, bo, prescriptionItemBoList);
            if (map != null && (Boolean) map.get("flag")) {
                // 应收
                BigDecimal costs = (BigDecimal) map.get("costs");
                // 实收
                BigDecimal paidUpAmount = (BigDecimal) map.get("paidUpAmount");
                // 更新clinic_orders 实收、应收金额
                clinicOrdersService.updateCharges(costs, paidUpAmount, bo.getItemClass(), BeanUtil.toBean(clinicOrdersVo, ClinicOrders.class));
                // 更新主表orderId
                baseMapper.update(null, new LambdaUpdateWrapper<PrescriptionApply>()
                        .set(PrescriptionApply::getOrdersId, clinicOrdersVo.getId())
                        .eq(PrescriptionApply::getApplyId, add.getApplyId()));
            }
            // 是否收取代煎费用
            if (StringUtils.equals(bo.getIsDecoction(), "0")) {
                clinicOrderParam.setNum(bo.getRepetition());
                selectOrgDict(clinicOrderParam, bo, "clinic_dict");
            }
            //修改接诊医生doctor_id
            if (StringUtils.equals(bo.getInoroutFlag(), BaseConstants.IS_CLINIC)) {
                clinicMasterService.updateDoctorId(bo.getClinicId(), bo.getIsUpdateDoctorId());
            }
        }
        return flag;
    }

    public void selectOrgDict(ClinicOrderParam clinicOrderParam, PrescriptionApplyBo bo, String dictType) {
        SysOrgDict sysOrgDict = new SysOrgDict();
        sysOrgDict.setOrgId(bo.getOrgId());
        sysOrgDict.setType(dictType);
        sysOrgDict.setValue(bo.getIsDecoction());
        // 保存clinicOrder、clinicOrderCost信息
        List<SysOrgDict> sysOrgDictList = orgDictDataService.selectList(sysOrgDict);
        if (CollectionUtils.isNotEmpty(sysOrgDictList)) {
            List<ApplyItemBo> applyItemBoList = new ArrayList<>();
            sysOrgDictList.forEach(sysOrgDict1 -> {
                ApplyItemBo applyItemBo = new ApplyItemBo();
//                applyItemBo.setApplyItemId(labItem.getId());
                applyItemBo.setClinicItemId(sysOrgDict1.getClinicItemId());
//                applyItemBo.setItemClass(BaseConstants.ITEM_CLASS.EXAM);
                applyItemBoList.add(applyItemBo);
            });
            clinicOrderParam.setApplyItemBoList(applyItemBoList);
        }
        ClinicOrders clinicOrders = clinicOrdersService.initClinicOrders(clinicOrderParam);
        // 新增处置治疗信息 start
        clinicOrderParam.setClinicOrdersId(clinicOrders.getId());
        clinicOrderParam.setGroupNo(clinicOrders.getGroupNo());
        outpTreatRecService.saveByBo(clinicOrderParam);
    }

    /**
     * 保存处方明细
     *
     * @param bo
     */
    @Transactional
    public List<PrescriptionItemBo> savePrescriptionItem(PrescriptionApplyBo bo) {
        List<PrescriptionItemBo> prescriptionItemBoList = bo.getPrescriptionItemBoList();
        prescriptionItemBoList.forEach(prescriptionItemBo -> {
            // 发药状态
            prescriptionItemBo.setConfirmFlag(BaseConstants.CONFIRM_FLAG.UNISSUED);
            prescriptionItemBo.setApplyId(bo.getApplyId());
            prescriptionItemBo.setRepetition(bo.getRepetition());
            prescriptionItemBo.setChargeFlag(bo.getChargeFlag());
            prescriptionItemBo.setIsSkin(StringUtils.equals(prescriptionItemBo.getIsSkin(), "true") ? UserConstants.YES : UserConstants.NO);
            prescriptionItemBo.setNoSkin(StringUtils.equals(prescriptionItemBo.getIsSkin(), "true") ? UserConstants.NO : UserConstants.YES);
            prescriptionItemBo.setOrgId(bo.getOrgId());
            prescriptionItemBo.setDelFlag("0");
        });
        List<PrescriptionItem> prescriptionItems = prescriptionItemService.saveBatch(prescriptionItemBoList);
        return BeanUtil.copyToList(prescriptionItems, PrescriptionItemBo.class);
    }

    /**
     * 保存 clinicOrdersCost
     **/
    public Map<String, Object> saveClinicOrderCost(ClinicOrdersVo vo, PrescriptionApplyBo bo, List<PrescriptionItemBo> prescriptionItemBoList) {
        List<ClinicOrdersCost> clinicOrdersCostList = new ArrayList<>();
        Map<String, Object> map = new HashMap<String, Object>();
        // 应收
        BigDecimal amount = new BigDecimal(BigInteger.ZERO);
        // 实收
        BigDecimal paidUpAmount = new BigDecimal(BigInteger.ZERO);
        for (PrescriptionItemBo itemBo : prescriptionItemBoList) {
            ClinicOrdersCost clinicOrdersCost = BeanUtil.toBean(itemBo, ClinicOrdersCost.class);
            clinicOrdersCost.initEntity();
            clinicOrdersCost.setConfirmFlag(BaseConstants.CONFIRM_FLAG.UNISSUED);
            clinicOrdersCost.setClinicId(vo.getClinicId());
            clinicOrdersCost.setPatientId(vo.getPatientId());
            clinicOrdersCost.setOrdersId(vo.getId());
            clinicOrdersCost.setPackItemName(itemBo.getDrugName());
            clinicOrdersCost.setItemName(itemBo.getDrugName());
            clinicOrdersCost.setItemCode(itemBo.getDrugCode());
            clinicOrdersCost.setDiffCost(BigDecimal.valueOf(1));
            clinicOrdersCost.setNum(itemBo.getNum() * bo.getRepetition());
            clinicOrdersCost.setClinicItemId(itemBo.getPriceId());
            clinicOrdersCost.setApplyItemId(itemBo.getItemId());
            clinicOrdersCost.setApplyNo(vo.getApplyNo());
            if (StringUtils.equals(itemBo.getPackSize(), BaseConstants.IS_SMALL_PACK)) {
                clinicOrdersCost.setUnit(itemBo.getMinUnits());
                clinicOrdersCost.setSpec(itemBo.getMinSpec());
            } else {
                clinicOrdersCost.setUnit(itemBo.getPackageUnits());
                clinicOrdersCost.setSpec(itemBo.getPackageSpec());
            }
            // 获取诊疗项目所有价表项目
            List<ClinicItemDictVo> clinicItemsAndPriceList = remoteClinicItemDictService.
                    getClinicItemsAndPriceList(vo.getOrgId(), new ArrayList<>(), Collections.singletonList(itemBo.getPriceId()));
            if (CollectionUtil.isNotEmpty(clinicItemsAndPriceList)) {
                ClinicItemDictVo clinicItemDictVo = clinicItemsAndPriceList.get(0);
                List<PriceListVo> priceListVoList = clinicItemDictVo.getPriceListVoList();
                if (CollectionUtil.isNotEmpty(priceListVoList)) {
                    PriceListVo priceListVo = priceListVoList.get(0);
                    clinicOrdersCost.setItemClass(priceListVo.getItemClass());
                    clinicOrdersCost.setPriceId(priceListVo.getPriceId());
                    clinicOrdersCost.setTradePrice(priceListVo.getTradePrice());
                    clinicOrdersCost.setNetworkPrice(priceListVo.getNetworkPrice());
                    clinicOrdersCost.setPrice(itemBo.getPrice());
                    clinicOrdersCost.setCosts(BigDecimal.valueOf(clinicOrdersCost.getNum()).multiply(itemBo.getPrice()));
                    clinicOrdersCost.setCharges(BigDecimal.valueOf(clinicOrdersCost.getNum()).multiply(itemBo.getPrice()));
                    clinicOrdersCost.setClassOnRcpt(priceListVo.getClassOnRcpt());
                    clinicOrdersCost.setClassOnReckoning(priceListVo.getClassOnReckoning());
                    clinicOrdersCost.setSubjCode(priceListVo.getSubjCode());
                    clinicOrdersCost.setCoefficient(priceListVo.getPreferPrice());
                    amount = amount.add(clinicOrdersCost.getCosts());
                    paidUpAmount = paidUpAmount.add(clinicOrdersCost.getCharges());
                }
            } else {
                throw new RuntimeException("药品没有增加诊疗项目对照，请联系信息科对照后再操作。");
            }
            clinicOrdersCostList.add(clinicOrdersCost);
        }
        boolean b = clinicOrdersCostService.saveBatch(clinicOrdersCostList);
        map.put("flag", b);
        map.put("costs", amount);
        // 实收
        map.put("paidUpAmount", paidUpAmount);
        return map;
    }

    /**
     * 修改处方主表
     */
    @Override
    public Boolean updateByBo(PrescriptionApplyBo bo) {
        PrescriptionApply update = BeanUtil.toBean(bo, PrescriptionApply.class);
        update.setUpdateBy(LoginHelper.getLoginUser().getNickName());
        update.setUpdateTime(new Date());
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(PrescriptionApply entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除处方主表
     */
    @Override
    @Transactional
    public Boolean deleteWithValidById(String applyId, Boolean isValid) {
        Boolean b = false;
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
            PrescriptionApplyVo prescriptionApplyVo = baseMapper.selectVoOne(Wrappers.<PrescriptionApply>lambdaQuery()
                    .eq(PrescriptionApply::getApplyId, applyId)
                    .eq(PrescriptionApply::getDelFlag, "0")
            );
            if (ObjectUtil.isNotNull(prescriptionApplyVo)) {
                if (!StringUtils.equals(prescriptionApplyVo.getChargeFlag(), BaseConstants.CHARGE_FLAG_DICT.ONE)) {
                    throw new RuntimeException("此处方已收费或已退费不能删除，只能删除未收费的处方，请刷新页面");
                } else {
                    b = deleteInfo(prescriptionApplyVo);
                }
            } else {
                throw new RuntimeException("此处方已删除，请刷新页面");
            }
        }
        return b;
    }

    /**
     * 删除处方记录
     *
     * @param vo
     * @return
     */
    @GlobalTransactional
    private Boolean deleteInfo(PrescriptionApplyVo vo) {
        baseMapper.deleteById(vo.getApplyId());
        prescriptionItemService.deleteByApplyId(vo.getApplyId());
        outpTreatRecService.deleteByBo(vo.getOrgId(), vo.getApplyNo());
        return clinicOrdersService.deleteByBo(vo.getOrgId(), vo.getApplyNo());
    }

    @Override
    public Boolean refundApplication(String id, String chargeFlag) {
        PrescriptionApplyVo vo = baseMapper.selectVoById(id);
        if (ObjectUtil.isNotNull(vo)) {
            if (StringUtils.equals(chargeFlag, BaseConstants.CHARGE_FLAG_DICT.TWO)) {
                // 申请退费
                if (!StringUtils.equals(vo.getChargeFlag(), BaseConstants.CHARGE_FLAG_DICT.THREE)) {
                    throw new RuntimeException("申请单状态已改变，申请退费失败请刷新列表。");
                }
            } else if (StringUtils.equals(chargeFlag, BaseConstants.CHARGE_FLAG_DICT.THREE)) {
                // 撤销退费
                if (!StringUtils.equals(vo.getChargeFlag(), BaseConstants.CHARGE_FLAG_DICT.TWO)) {
                    throw new RuntimeException("申请单状态已改变，撤销退费失败请刷新列表。");
                }
            }
        }
        if (ObjectUtil.isNotNull(vo)) {
            // 判断药品是否已发放
            if (StringUtils.equals(vo.getChargeFlag(), BaseConstants.CONFIRM_FLAG.ISSUED)) {
                return baseMapper.update(null, new LambdaUpdateWrapper<PrescriptionApply>()
                        // 修改为 科室确认退费(药)中
                        .set(PrescriptionApply::getChargeFlag, BaseConstants.CHARGE_FLAG_DICT.SIX)
                        .eq(PrescriptionApply::getApplyId, id)) > 0;
            }
            // 修改主记录
            boolean b = baseMapper.update(null, new LambdaUpdateWrapper<PrescriptionApply>()
                    .set(PrescriptionApply::getChargeFlag, chargeFlag)
                    .eq(PrescriptionApply::getApplyId, id)) > 0;
            // 修改门诊医嘱记录
            LambdaUpdateWrapper<ClinicOrders> ordersLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            ordersLambdaUpdateWrapper.set(ClinicOrders::getChargeFlag, chargeFlag);
            ordersLambdaUpdateWrapper.eq(ClinicOrders::getId, vo.getOrdersId());
            ClinicOrdersBo clinicOrdersBo = new ClinicOrdersBo();
            clinicOrdersBo.setChargeFlag(chargeFlag);
            clinicOrdersBo.setId(vo.getOrdersId());
            clinicOrdersBo.setOrgId(vo.getOrgId());
            clinicOrdersBo.setItemClass(vo.getItemClass());
            boolean b1 = clinicOrdersService.updateChargeFlag(clinicOrdersBo);
            // 修改门诊诊疗项目记录
            LambdaUpdateWrapper<OutpTreatRec> outpTreatRecLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            outpTreatRecLambdaUpdateWrapper.set(OutpTreatRec::getChargeFlag, chargeFlag);
            outpTreatRecLambdaUpdateWrapper.eq(OutpTreatRec::getOrgId, vo.getOrgId());
            outpTreatRecLambdaUpdateWrapper.eq(OutpTreatRec::getApplyNo, vo.getApplyNo());
            boolean b2 = outpTreatRecService.update(outpTreatRecLambdaUpdateWrapper);
            // 修改门诊收费表收费状态标志
            OutpFeesMasterBo outpFeesMasterBo = new OutpFeesMasterBo();
            outpFeesMasterBo.setOrdersId(vo.getOrdersId());
            outpFeesMasterBo.setChargeFlag(chargeFlag);
            outpFeesMasterService.updateChargeFlag(outpFeesMasterBo);
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }
}
